﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Snake.Scripts
{
    internal class BigSnake : Singleton<BigSnake>
    {
        private List<Point> body = new List<Point>();

        EDirection dir = EDirection.Right;

        Point tail;

        public void Start()
        {
            body.Add(new Point(4, 2));
            body.Add(new Point(3, 2));
            body.Add(new Point(2, 2));
        }

        public void Update()
        {
            if (GameOver()) return;
            Turn();
            Eat();
            Move();
        }

        public void Move()
        {
            Point offset = new Point(0, 0);
            switch (dir)
            {
                case EDirection.Up:
                    offset = new Point(0, -1);
                    break;
                case EDirection.Down:
                    offset = new Point(0, 1);
                    break;
                case EDirection.Left:
                    offset = new Point(-1, 0);
                    break;
                case EDirection.Right:
                    offset = new Point(1, 0);
                    break;
                default:
                    break;
            }
            body.Insert(0, body[0] + offset);
            tail = body[body.Count - 1];
            body.RemoveAt(body.Count - 1);
        }

        public void Draw()
        {
            for (int i = body.Count - 1; i >= 0; i--) // j - 列 从蛇尾往蛇头画，防止蛇头被蛇尾覆盖
            {
                Point pt = body[i];
                Console.SetCursorPosition(pt.x*2, pt.y);
                Console.ForegroundColor = i == 0 ? ConsoleColor.Red : ConsoleColor.Green;
                Console.Write('o');
            }
        }

        private void Eat()
        {
            Point head = body[0];
            if (Map.Instance.GetAt(head) == EPointType.Food)
            {
                Map.Instance.SetAt(head, EPointType.Blank);
                body.Add(tail);
                Map.Instance.GenFood();
            }
        }

        private void Turn()
        {
            if (Console.KeyAvailable)
            {
                var key = Console.ReadKey(true).Key;

                if (key == ConsoleKey.W && dir != EDirection.Down)
                {
                    dir = EDirection.Up;
                }
                else if (key == ConsoleKey.S && dir != EDirection.Up)
                {
                    dir = EDirection.Down;
                }
                else if (key == ConsoleKey.A && dir != EDirection.Right)
                {
                    dir = EDirection.Left;
                }
                else if (key == ConsoleKey.D && dir != EDirection.Left)
                {
                    dir = EDirection.Right;
                }
            }
        }

        private bool GameOver()
        {
            Point head = body[0];
            if(Map.Instance.GetAt(head) == EPointType.Wall)
            {
                return true;
            }
            for (int i = 1; i < body.Count; i++)
            {
                if (body[i] == head) return true;
            }
            return false;
        }
    }
}
